package TDA_Lista;

import java.util.Iterator;

/**Interface propuesta en [GT, Fragmento de codigo 6.5]
 * Relaciona una lista con el concepto de posicion. */
public interface PositionList<E> extends Iterable<E>{
	/**Retorna el numero de elementos en la lista.
	 * @return el numero de elementos en la lista.  */
	public int size();
	/**Retorna si la lista esta vacia o no.
	 * @return true si la lista esta vacia, false caso contrario. */
	public boolean isEmpty();
	/**Retorna el primer nodo de la lista. 
	 * @return la posicion del primer nodo de la lista. 
	 * @exception EmptyListException: si la lista esta vacia. */
	public Position<E> first()throws EmptyListException;
	/**Retorna el ultimo nodo en la lista. 
	 * @return la posicion del ultimo nodo de la lista. 
	 * @exception EmptyListException: si la lista esta vacia. */
	public Position<E> last()throws EmptyListException;
	/**Retorna el nodo siguiente a un nodo dado en la lista. 
	 * @param p: posicion sobre la cual quiero obtener el nodo siguiente.
	 * @return la posicion del siguiente a un nodo dado en la lista.
	 * @exception InvalidPositionException: si el argumento de la posicion no es valido.
	 * @exception BoundaryViolationException: si la posicion esta fuera del rango de la lista. */
	public Position<E> next(Position<E> p)throws InvalidPositionException, BoundaryViolationException;
	/**Retorna el nodo anterior a un nodo dado en la lista. 
	 * @param p: posicion sobre la cual quiero obtener el nodo anterior. 
	 * @return la posicion del anterior a un nodo dado en la lista. 
	 * @exception InvalidPositionException: si el argumento de la posicion no es valido.
	 * @exception BoundaryViolationException: si la posicion esta fuera del rango de la lista. */
	public Position<E> prev(Position<E> p)throws InvalidPositionException, BoundaryViolationException;
	/**Inserta un elemento al principio de la lista.
	 * @param e: elemento a insertar en la lista. */
	public void addFirst(E e);
	/**Inserta un elemento al final de la lista. 
	 * @param e: elemento a insertar en la lista. */
	public void addLast(E e);
	/**Inserta un elemento antes de un nodo dado en la lista. 
	 * @param p: despues de dicha posicion se insertara un elemento. 
	 * @param e: elemento a insertar en la lista.
	 * @exception InvalidPositionException: si el argumento de la posicion no es valido. */
	public void addAfter(Position<E> p, E e)throws InvalidPositionException;
	/**Inserta un elemento despues de un nodo dado en la lista. 
	 * @param p: antes de dicha posicion se insertara un elemento. 
	 * @param e: elemento a insertar en la lista.
	 * @exception InvalidPositionException: si el argumento de la posicion no es valido.*/
	public void addBefore(Position<E> p, E e)throws InvalidPositionException;
	/**Remueve un nodo de la lista, retornando el elemento almacenado en el. 
	 * @param p: posicion en la que se encuentra el elemento a eliminar. 
	 * @return el elemento eliminado.
	 * @exception InvalidPositionException: si el argumento de la posicion no es valido. */
	public E remove(Position<E> p)throws InvalidPositionException;
	/**Reemplaza el elemento almacenado en un nodo dado, retornando el elemento viejo. 
	 * @param p: posicion en la que se encuentra el elemento a modificar. 
	 * @param e: elemento que quiero insertar.
	 * @return el elemento que se ha modificado.
	 * @exception InvalidPositionException: si el argumento de la posicion no es valido. */
	public E set(Position<E> p, E e)throws InvalidPositionException;
	/**Devuelve un iterador para recorrer los elementos de la lista. 
	 * @return un iterador de la lista. */
	public Iterator<E> iterator(); 
}
